<?php


/**
 * A PHP class library that abstracts PHP language constructs
 * with the goal is to facilitate automated PHP code generation
 * 
 * The idea is to have PHP classes that represent each (or the most commonly 
 * used) PHP language constructs from code units and namespaces to statements
 * and expressions. For instance, a class named CodeNamespace would represent
 * a PHP namespace and would contain members like $Comments and $Types.
 * A class named TypeDeclaration, in turn, would contain members like $Comments, 
 * $Members and $BaseTypes etc.
 * These classes could be used to programatically construct an object tree
 * which could be than translated into PHP source code. 
 *
 * @package UC_PHPCodeModel
 * @author Uros Calakovic  
 */


/**
 * My attempt at a PHP autoloader function
 * All classes are in separate .php files with corresponding names
 * 
 * @param string $className The name of the class to be loaded
 */

function autoloader($className)
{
    include_once $className . '.php';
}

spl_autoload_register('autoloader');

/**
 * The PHPCodeProvider class is the entry point for generating PHP code
 * from a PHPCodeModel object tree.
 * 
 * PHPCodeProvider contains generate* methods that allow you to generate
 * PHP code for:
 * - Code unit (that can contain one or more namespaces)
 * - Namespace
 * - Type (class or interface)
 * - Statement
 * - Expression
 * PHPCodeProvider is a facade to another class PHPCodeGenerator that does all
 * the dirty work of generating PHP source code from the object tree.
 *
 * @package UC_PHPCodeModel
 * @author Uros Calakovic
 */
class PHPCodeProvider
{
    /**
     * PHPCodeProvider contructor
     * 
     * The only purpose of the constructor is to initialize the private
     * PHPCodeGenerator instance. The PHPCodeGenerator constructor
     * is passed the reference to this PHPCodeProvider instance
     * in an attempt to make sure that a PHPCodeGenerator instance
     * is not generated independently of a PHPCodeProvider instance.
     */
    
    public function __construct()
    {
        $this->generator = new PHPCodeGenerator($this);
    }
    
    /**
     * Returns an escaped identifier if $name is not a valid PHP variable name.
     * If $name contains invalid characters returns false
     * 
     * @param string $name
     * @return string
     * @see PHPCodeGenerator::createEscapedIdentifier()
     * @example ../Examples/PHPCodeProvider_createEscapedIdentifier.php
     *
     * @assert('validName') == 'validName'
     * @assert('15invalid') == '_15invalid'
     * @assert('**invalid') == false
     * @assert('var namei') == false
     * @assert('special$/') == false
     */
    
    public function createEscapedIdentifier($name)
    {
        return $this->generator->createEscapedIdentifier($name);
    }

    /**
     * Returns true if $value is a valid PHP identifier, else returns false
     * 
     * @param string $value
     * @return bool
     * @see PHPCodeGenerator::isValidIdentifier()
     * @example ../Examples/PHPCodeProvider_isValidIdentifier.php 
     *
     * @assert('validName') == true
     * @assert('15invalid') == false
     * @assert('**invalid') == false
     * @assert('var namei') == false
     * @assert('special$/') == false
     */
    
    public function isValidIdentifier($value)
    {
        return $this->generator->isValidIdentifier($value);
    }
    
    /**
     * Generates PHP code from an instance of the CodeUnit class.
     * 
     * $options is used to specify code generation options
     * $writer contains the generated code after the function call
     * 
     * @param CodeUnit $codeUnit the code unit to be generated
     * @param IndentedTextWriter $writer contains the generated code
     * @param CodeGeneratorOptions $options options for code generation
     * @see PHPCodeGenerator::generateCodeFromCodeUnit()
     * @example ../Examples/PHPCodeProvider_generateCodeFromCodeUnit.php
     */
    
    public function generateCodeFromCodeUnit(CodeUnit $codeUnit, 
        IndentedTextWriter $writer, CodeGeneratorOptions $options)
    {
        $this->generator->generateCodeFromCodeUnit($codeUnit, $writer, $options);
    }

    /**
     * Generates code from an instance of the Expression class.
     * 
     * $expression can be an instance of any of the classes
     * inherited from the Expression class, like BinaryOperatorExpression
     * or ArrayCreateExpression.
     * 
     * @param Expression $expression the expression to be generated
     * @param IndentedTextWriter $writer contains the generated code
     * @param CodeGeneratorOptions $options options for code generation
     * @see PHPCodeGenerator::generateCodeFromExpression()
     * @example ../Examples/PHPCodeProvider_generateCodeFromExpression.php
     */
    
    public function generateCodeFromExpression(Expression $expression, 
        IndentedTextWriter $writer, CodeGeneratorOptions $options)
    {
        $this->generator->generateCodeFromExpression($expression, $writer, $options);
    }
    
    /**
     * Generates code from an instance of the CodeNamespace class
     * 
     * $codeNamespace is the PHP namespace to be generated.
     * It has members like Comments and Types (a collection of PHP 
     * classes and interfaces).
     * 
     * @param CodeNamespace $codeNamespace The PHP namespace to be generated
     * @param IndentedTextWriter $writer Contains the generated code
     * @param CodeGeneratorOptions $options Options for code generation
     * @see PHPCodeGenerator::generateCodeFromNamespace()
     * @example ../Examples/PHPCodeProvider_generateCodeFromNamespace.php
     */
    
    public function generateCodeFromNamespace(CodeNamespace $codeNamespace,
        IndentedTextWriter $writer, CodeGeneratorOptions $options)
    {
        $this->generator->generateCodeFromNamespace($codeNamespace, $writer, $options);
    }
    
    /**
     * Generates code from an instance of the Statement class.
     * 
     * $statement can be an instance of any of the classes
     * inherited from the Statement class, like
     * 
     * @param Statement $statement The PHP statement to be generated
     * @param IndentedTextWriter $writer Contains the generated code
     * @param CodeGeneratorOptions $options Options for code generation
     * @see PHPCodeGenerator::generateCodeFromStatement()
     * @example ../Examples/PHPCodeProvider_generateCodeFromStatement.php
     */
    
    public function generateCodeFromStatement(Statement $statement,
        IndentedTextWriter $writer, CodeGeneratorOptions $options)
    {
        $this->generator->generateCodeFromStatement($statement, $writer, $options);
    }
    
    /**
     * Generates code from an instance of the TypeDeclaration class
     * 
     * TypeDeclaration can represent a PHP class or interface
     * and has members like BaseTypes, Comments and Members.
     * 
     * @param TypeDeclaration $codeType The class / interface to be generated
     * @param IndentedTextWriter $writer Contains the generated code
     * @param CodeGeneratorOptions $options Options for code generation
     * @see PHPCodeGenerator::generateCodeFromType()
     * @example ../Examples/PHPCodeProvider_generateCodeFromType.php
     */
    
    public function generateCodeFromType(TypeDeclaration $codeType, 
        IndentedTextWriter $writer, CodeGeneratorOptions $options)
    {
        $this->generator->generateCodeFromType($codeType, $writer, $options);
    }

    /**
     * The isInitialized method is meant to be used by the PHPCodeGenerator
     * constructor in an attempt to make sure that a PHPCodeGenerator
     * instance is not created independently of a PHPCodeProvider instance.
     * 
     * @return bool
     */
    
    public function isInitialized()
    {
        return $this->generator instanceof PHPCodeGenerator ? true : false;
    }
    
    /**
     * The private instance of the PHPCodeGenerator class
     * 
     * @var PHPCodeGenerator 
     * @see PHPCodeGenerator
     */
    
    private $generator;
}

?>
